SwiftUI+RealityKit 超初級編 – デフォルトテンプレートのコードを読み解く
アメリカでのApple Vision Proの発売日が決まり、心がワクワクしている方も多いのではないでしょうか。
VisionOSでの開発を行う前に今一度、iOSでのAR開発を勉強しようと思い、少しずつ学んでいくことにしました。
まずは超初級編として、デフォルトのARアプリを作成してコードを読み解き、実機で立ち上げるところから試していきます。
はじめに
今回の記事では、Argumented Reality Appテンプレートで作成したプロジェクトのARView生成時のコードを読み解く記事になっており、対象読者はSwiftUI+RealityKitに触れたことのない方を想定しています。
環境
- Xcode 15.2
プロジェクトの作成
Xcodeを立ち上げて、Create New Projectを選択し、新規プロジェクトを作成します。
今回は、Argumented Reality Appのテンプレートを選択して作成します。
あとは、任意のプロジェクト名を付けて、任意の保存先を指定するだけです。
今回は、プロジェクト名をHello-ar-realitykit-swiftui
と命名しました。
デフォルトの構成
作成時のプロジェクト構成は下記になっています。
デフォルトのコード
Xcode 15.2でArgument Reality Appのテンプレートでプロジェクトを作成した場合、ContentViewファイルのデフォルトのコードは下記になっています。
import SwiftUI import RealityKit struct ContentView : View { var body: some View { ARViewContainer().edgesIgnoringSafeArea(.all) } } struct ARViewContainer: UIViewRepresentable { func makeUIView(context: Context) -> ARView { let arView = ARView(frame: .zero) // Create a cube model let mesh = MeshResource.generateBox(size: 0.1, cornerRadius: 0.005) let material = SimpleMaterial(color: .gray, roughness: 0.15, isMetallic: true) let model = ModelEntity(mesh: mesh, materials: [material]) model.transform.translation.y = 0.05 // Create horizontal plane anchor for the content let anchor = AnchorEntity(.plane(.horizontal, classification: .any, minimumBounds: SIMD2<Float>(0.2, 0.2))) anchor.children.append(model) // Add the horizontal plane anchor to the scene arView.scene.anchors.append(anchor) return arView } func updateUIView(_ uiView: ARView, context: Context) {} } #Preview { ContentView() }
struct ContentView
ContentView
構造体の中では、AR画面を表示する為にARViewContainer()
を呼び出し、デバイスいっぱいに表示する為に.edgesIgnoringSafeArea(.all)
を指定しています。
struct ARViewContainer
SwiftUIでARView
を使用するには、現時点ではUIViewRepresentable
でラップして使用する必要があります。UIViewRepresentable
の説明については本筋とは違う為、今回は省略します。
makeUIView
func makeUIView(context: Context) -> ARView
ではARView
を呼び出して、その画面上にキューブ型のモデルが設置されるコードが書かれています。
let arView = ARView(frame: .zero)
まずはARView
を生成しています。
// Create a cube model let mesh = MeshResource.generateBox(size: 0.1, cornerRadius: 0.005) let material = SimpleMaterial(color: .gray, roughness: 0.15, isMetallic: true) let model = ModelEntity(mesh: mesh, materials: [material]) model.transform.translation.y = 0.05
その後、3Dモデルを作成する処理が書かれています。
まず、generateBox(size: 0.1, cornerRadius: 0.005)
でキューブ形状のメッシュを生成しています。size
に0.1
が指定してあります。RealityKitではメートル単位が基準となっている為、1辺が0.1m(10cm)のキューブ形状のメッシュで生成されます。また、cornerRadius
が指定されている為、角丸になります。
SimpleMaterial(color: .gray, roughness: 0.15, isMetallic: true)
でメッシュに載せるマテリアルを生成しています。色がグレー、roughness
は物質表面の粗さを表す数値、isMetallic
でメタリックの表現を適用するかを指定しています。
ModelEntity(mesh: mesh, materials: [material])
では、上記で作成したメッシュ、マテリアルを使用してモデルを生成しています。
最後にmodel.transform.translation.y = 0.05
では、このモデルの位置をアンカーからy軸方向に0.05m上に配置されるように位置を移動させています。
モデルの作成は以上になるので、次に作成したモデルとシーンを結びつける為のアンカーを作成しています。
// Create horizontal plane anchor for the content let anchor = AnchorEntity(.plane(.horizontal, classification: .any, minimumBounds: SIMD2<Float>(0.2, 0.2))) anchor.children.append(model)
AnchorEntity
の生成時のターゲットに.plane
が指定してあり、平面を検出することが分かります。また、ターゲットの制約に.horizontal
が指定してあるので水平方向の平面のみを検出します。
classification
では.any
を指定していますが、指定できる分類は、下記のように壁やテーブルなど様々なものを指定出来ます。今回は.any
を指定している為、全ての平面から検出します。
- wall
- floor
- ceiling
- table
- seat
- any
minimumBounds
は、検出される平面の最小サイズを指定しています。ここでは幅と高さがそれぞれ0.2m以上の平面が対象になっています。
最後に今回生成しているAnchorEntity
の子として、すでに生成しているモデルを追加しています。
モデルをARView
上に設置する準備が整ったので仕上げになります。
// Add the horizontal plane anchor to the scene arView.scene.anchors.append(anchor)
生成した平面アンカーをARView
のシーンのアンカーに追加しています。
以上がデフォルトでの3Dオブジェクト表示の処理の概要になります。
updateUIView
の処理は今回実施しないので説明は省略します。
実機で確認
ARViewの確認にはカメラが必要な為、実機で確認する必要があります。
今回はテーブル上で平面検出を試しました。キューブ形状のモデルがテーブルの上に表示され、しっかりとテーブルとモデルとのy軸方向の隙間も確認出来ました。
おわりに
今回はデフォルトのコードを確認して立ち上げただけですが、3DオブジェクトをAR空間に表示する仕組みの理解が少しだけ深まったような気がします。
さらに理解を深めていく為、引き続き学習を進めていきます。